//
//  XTNetWorkManger.swift
//  MyBlog
//
//  Created by victor on 16/12/15.
//  Copyright © 2016年 victor. All rights reserved.
//

import UIKit
import AFNetworking

/// swift 的枚举支持任意类型
/// switch / enum oc中都是只支持整数
enum XTHTTPMethod {
    case GET
    case POST
}

/// 网络管理工具
class XTNetWorkManger: AFHTTPSessionManager {
    
    //静态区/常量/闭包
    //在第一次访问时执行闭包，并且将结果保存在 sharedManager 常量中
    static let shared: XTNetWorkManger = {
        
        // 实例化对象
        let instance = XTNetWorkManger()
        
        // 设置响应的反序列化支持的数据类型
        instance.responseSerializer.acceptableContentTypes?.insert("text/plain")
        
        // 返回对象
        return instance
    }()
    
    /// 用户账户的懒加载属性
    lazy var userAccount = XTUserAccount()
    
    /// 用户登录标记(计算型属性)
    var userLogon: Bool {
        return userAccount.access_token != nil
    }
    
    /// 专门负责拼接token的网络请求方法
    func tokenRequest(type: XTHTTPMethod = .GET, url: String, parameters:[String: Any]?,
                      callBack:@escaping (_ json: Any?,_ isSuccess: Bool)->()) {
        
        // 处理 token 字典
        // 判断是否为nil，为nil直接返回，程序执行过程中，一般 token 不会为 nil
        guard let token = userAccount.access_token else {
            
            // 发送通知，提示用户登录
            print("没有token！需要登录")
            
            NotificationCenter.default.post(
                name: NSNotification.Name(rawValue: XTUserShouldLoginNotification),
                object: nil)
            
            callBack(nil,false)
            
            return
        }
        
        // 判断参数字典是否存在，如果为nil，应该新建字典
        var parameters = parameters
        if parameters == nil {
            // 实例化字典
            parameters = [String: Any]()
        }
        
        // 设置参数字典，代码在此处一定有值
        parameters!["access_token"] = token as Any?
        
        // 调用 request 发起真正的网络请求方法
        request(url: url, parameters: parameters, callBack: callBack)
        
    }
    
    /// 封装AFN的 GET / POST 请求
    ///
    /// - Parameters:
    ///   - type: GET / POST
    ///   - url: urlString
    ///   - parameters: 参数字典
    ///   - callBack: 完成回调(json(字典/数组)，是否成功)
    func request(type: XTHTTPMethod = .GET,url: String,parameters:[String: Any]?,
                 callBack:@escaping (_ json: Any?,_ isSuccess: Bool)->()) {
        
        let success = { (task: URLSessionDataTask,json: Any?) ->() in
            callBack(json,true)
        }
        
        // 失败回调
        let failure = { (task: URLSessionDataTask?,error: Error) ->() in
            
            // 针对403 处理用户 token 过期(? 可选不能参与计算，但是可以参与比较)
            // 过期 服务器返回 403 即身份验证没有通过
            // 对于测试用户(应用程序还没有提交给新浪微博审核)每天的刷新量是有限的
            // 超出上限token会被锁定一段时间
            // 解决办法，新建一个应用程序
            // 父类往子类转 用 as 做强行转换
            if (task?.response as? HTTPURLResponse)?.statusCode == 403 {
                print("token过期了")
                
                // 发送通知，提示用户再次登录(本方法不知道被谁调用，谁接收到通知谁处理)
                NotificationCenter.default.post(
                    name: NSNotification.Name(rawValue: XTUserShouldLoginNotification),
                    object: "bad token")
            }
            
            print("网络请求错误\(error)")
            callBack(nil,false)
        }
        
        if type == .GET {
            get(url, parameters: parameters, progress: nil, success: success, failure: failure)
        } else {
            post(url, parameters: parameters, progress: nil, success: success, failure: failure)
        }
    
    }
}
